package com.yx.springai.chatclient.controller;

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.yx.springai.chatclient.advisor.RereadingAdvisor;
import com.yx.springai.chatclient.domain.ModelOption;
import com.yx.springai.chatclient.entity.Song;
import com.yx.springai.chatclient.service.ToolsService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.HashMap;
import java.util.List;

@RestController
public class ChatController {
    @Autowired
    private ChatMemory chatMemory;


    HashMap<String, ChatModel> modelHashMap = new HashMap<>();
    //DeepSeekChatModel deepSeekChatModel = new DeepSeekChatModel();
    public ChatController(DashScopeChatModel dashScopeChatModel){
        modelHashMap.put("dashScope",dashScopeChatModel);
        //modelHashMap.put("deepseek",deepSeekChatModel);
    }
    @RequestMapping(value = "chat",produces = "text/stream;charset=utf-8")
    public Flux<String> chat(String msg, ModelOption option){
        ChatModel chatModel = modelHashMap.get(option.getPlatform());
        ChatClient.Builder builder = ChatClient
                .builder(chatModel);
        ChatOptions chatOptions = ChatOptions.builder()
                .temperature(option.getTemperature())
                .build();
        ChatClient chatClient = builder
                //拦截器 (AOP) 记录日志等。。。
                //日志记录需配置文件设置日志级别
                .defaultAdvisors(
                        new SimpleLoggerAdvisor(),
//                        new SafeGuardAdvisor(List.of("好"),"敏感词请检查",2),
//                        new RereadingAdvisor(),
                        PromptChatMemoryAdvisor.builder(chatMemory).build() //多轮对话 记忆存储
                )
                //系统提示词
//                .defaultSystem("你是一个专业的外科医生 擅长更具各种外观分析 为患者建议 " +
//                        "让患者更快恢复 当前服务患者信息:姓名 {name},需要先确认患者名称是否正确")//系统提示词
                .defaultOptions(chatOptions).build();
        Flux<String> content = chatClient.prompt()
                //拦截器
                .advisors(
                        a -> a.param(ChatMemory.CONVERSATION_ID,"chat") //设置多轮对话用户ID
                )
//                .system(p -> p.param("name","张三")) //参数
                .user(msg).stream().content();
        return content;
    }


    @RequestMapping(value = "song")
    public List<Song> song(String msg, ModelOption option){
        ChatModel chatModel = modelHashMap.get(option.getPlatform());
        ChatClient.Builder builder = ChatClient
                .builder(chatModel);
        ChatOptions chatOptions = ChatOptions.builder()
                .temperature(option.getTemperature())
                .build();
        ChatClient chatClient = builder
                //拦截器 (AOP) 记录日志等。。。
                //日志记录需配置文件设置日志级别
                .defaultAdvisors(
                        new SimpleLoggerAdvisor(),
//                        new SafeGuardAdvisor(List.of("好"),"敏感词请检查",2),
//                        new RereadingAdvisor(),
                        PromptChatMemoryAdvisor.builder(chatMemory).build() //多轮对话 记忆存储
                )
                //系统提示词
                .defaultSystem("""
                        提供5首{name}的歌曲
                        """)//系统提示词
                .defaultOptions(chatOptions).build();
        List<Song> song = chatClient.prompt()
                //拦截器
                .advisors(
                        a -> a.param(ChatMemory.CONVERSATION_ID,"song") //设置多轮对话用户ID
                )
                .system(p -> p.param("name",msg)) //参数
//                .user(msg)
                .call().entity(List.class);
        return song;
    }


    @Autowired
    ToolsService toolsService;
    @GetMapping("/tools")
    public String testTools(String msg){
        System.out.println("tools start--------------------------------------------");
        ChatModel chatModel = modelHashMap.get("dashScope");
        ChatClient.Builder builder = ChatClient
                .builder(chatModel);
//        ChatOptions chatOptions = ChatOptions.builder()
//                .temperature(1D)
//                .build();
        ChatClient chatClient = builder
                .defaultTools(toolsService)
                //拦截器 (AOP) 记录日志等。。。
                //日志记录需配置文件设置日志级别
                .defaultAdvisors(
                        new SimpleLoggerAdvisor()
                        //PromptChatMemoryAdvisor.builder(chatMemory).build() //多轮对话 记忆存储
                )
//                .defaultOptions(chatOptions)
                .build();
        String content = chatClient.prompt()
                .advisors(
                        a -> a.param(ChatMemory.CONVERSATION_ID,"tools") //设置多轮对话用户ID
                ).user(msg).call().content();
        return content;
    }


    @Autowired
    ToolCallbackProvider provider;

    @GetMapping("/mcp")
    public Flux<String> mcp(String msg){
        System.out.println("mcp start--------------------------------------------");
        ChatModel chatModel = modelHashMap.get("dashScope");
        ChatClient.Builder builder = ChatClient
                .builder(chatModel);
        ChatClient chatClient = builder
                .defaultTools(toolsService)
                //拦截器 (AOP) 记录日志等。。。
                //日志记录需配置文件设置日志级别
                .defaultAdvisors(
                        new SimpleLoggerAdvisor(),
                        PromptChatMemoryAdvisor.builder(chatMemory).build() //多轮对话 记忆存储
                )
                .defaultToolCallbacks(provider)
                .build();
        Flux<String> content = chatClient.prompt()
                .advisors(
                        a -> a.param(ChatMemory.CONVERSATION_ID,"mcp") //设置多轮对话用户ID
                ).user(msg).stream().content();
        return content;
    }


    @GetMapping("/myMcp")
    public Flux<String> myMcp(String msg){
        System.out.println("mcp start--------------------------------------------");
        ChatModel chatModel = modelHashMap.get("dashScope");
        ChatClient.Builder builder = ChatClient
                .builder(chatModel);
        ChatClient chatClient = builder
                .defaultTools(toolsService)
                //拦截器 (AOP) 记录日志等。。。
                //日志记录需配置文件设置日志级别
                .defaultAdvisors(
                        new SimpleLoggerAdvisor(),
                        PromptChatMemoryAdvisor.builder(chatMemory).build() //多轮对话 记忆存储
                )
                .defaultToolCallbacks(provider)
                .build();
        Flux<String> content = chatClient.prompt()
                .advisors(
                        a -> a.param(ChatMemory.CONVERSATION_ID,"myMcp") //设置多轮对话用户ID
                ).user(msg).stream().content();
        return content;
    }
}
